package com.zanglikun.activity.util;

import java.util.*;

/**
 * Activity 执行器
 * 负责按顺序执行 Activity 链
 */
public class ActivityExecutor {
    private final List<Activity> activities = new ArrayList<>();
    private final List<ActivityListener> listeners = new ArrayList<>();

    public ActivityExecutor register(Activity activity) {
        if (activity != null) {
            activities.add(activity);
        }
        return this;
    }

    public ActivityExecutor addListener(ActivityListener listener) {
        listeners.add(listener);
        return this;
    }

    public void execute(ActivityContext context) {
        notifyStart(context);
        try {
            for (Activity activity : activities) {
                if (!context.isContinue()) {
                    break;
                }
                notifyBefore(activity, context);
                try {
                    boolean result = activity.execute(context);
                    notifyAfter(activity, context, null);
                    if (!result) {
                        context.stop();
                    }
                } catch (Exception e) {
                    notifyError(activity, context, e);
                    throw new ActivityExecutionException("Activity 执行失败: " + activity.getName(), e);
                }
            }
            notifyComplete(context);
        } catch (Exception e) {
            notifyFailed(context, e);
            throw e;
        }
    }

    private void notifyStart(ActivityContext context) {
        listeners.forEach(l -> l.onStart(context));
    }

    private void notifyBefore(Activity activity, ActivityContext context) {
        listeners.forEach(l -> l.onBefore(activity, context));
    }

    private void notifyAfter(Activity activity, ActivityContext context, Exception e) {
        listeners.forEach(l -> l.onAfter(activity, context, e));
    }

    private void notifyError(Activity activity, ActivityContext context, Exception e) {
        listeners.forEach(l -> l.onError(activity, context, e));
    }

    private void notifyComplete(ActivityContext context) {
        listeners.forEach(l -> l.onComplete(context));
    }

    private void notifyFailed(ActivityContext context, Exception e) {
        listeners.forEach(l -> l.onFailed(context, e));
    }
}